#ifndef TERRAIN_HPP_INCLUDED
#define TERRAIN_HPP_INCLUDED

#include <map>
#include <string>

#include "formula.hpp"
#include "model_fwd.hpp"
#include "terrain_fwd.hpp"
#include "texture.hpp"
#include "tile_logic.hpp"
#include "wml_node_fwd.hpp"

class rng;

namespace hex {

class terrain {
public:
	static void init(const wml::const_node_ptr& node);
	static const_terrain_ptr get(const std::string& key);
	struct parse_error {};
	explicit terrain(const wml::const_node_ptr& node);
	const std::string& id() const { return id_; }
	const graphics::texture& get_texture(const location& loc) const;
	const std::vector<graphics::texture>& get_textures() const;
	const_terrain_ptr underlying() const { return underlying_; }

	graphics::const_model_ptr get_model(rng& gen) const;
	int num_models() const { return num_models_; }

	typedef std::map<std::string, game_logic::const_formula_ptr> resource_map;

	const resource_map& resources() const { return resources_; }
	int move_cost() const;
	bool is_water() const { return water_; }

	int detail_level() const { return detail_level_; }

	std::pair<std::string,int> generate_bonus_resource() const;

	std::vector<int> generate_heights() const;
private:
	std::string id_;
	std::vector<graphics::texture> textures_;
	const_terrain_ptr underlying_;
	resource_map resources_;
	int move_cost_;
	bool water_;
	int detail_level_;

	std::vector<graphics::const_model_ptr> models_;
	int num_models_;

	game_logic::const_formula_ptr heights_;
	game_logic::const_formula_ptr bonus_resource_formula_;
};

}

#endif
